home *** CD-ROM | disk | FTP | other *** search
- /***+--------------------------------------------------------MYBACK.CMM
- Copyleft )( Blue Bird Computing, Inc., No rights reserved. Have fun!
-
- My Little Backup Program
-
- This program will ZIP up files with the Archive bit set in paths
- specified on the command line. It makes sure each Zip file will fit
- on a single floppy and keeps track of what is where so it can do
- incremental backups.
-
- Synopsis: Cenvi myback.cmm logfile directory1 [... directoryn]
-
- Input: logfile - A log file from a previous execution of
- this program that recorded what files
- were backed up and what Zip file(s) they
- may be found in.
-
- directory1 - A directory with files to be backed up.
- directoryn - More directories with files to be backed
- up.
-
- Output: Messages to stdout.
- The log file is updated.
- Zip files are created and copied to floppies.
-
- Calls: A ZIP utility.
-
- Used by: My mother (me too!).
-
- Environments: DOS, OS/2
-
- Dependencies: This program requires that the following enivronment
- variables be set:
-
- 1. MYBACK_WORK - To a fully qualified directoy
- on the hard disk that can be used as temporary
- storage while creating the ZIP files. Because
- of the way ZIP works, this drive must have free
- space equal to at least the value in MYBACK_SIZE.
-
- 2. MYBACK_DRIVE - To the floppy drive where the
- created ZIP files will be copied. This must
- not have a path, but this program doesn't
- check, so get it right.
- If this variable is set to "*" (a single
- asterisk) the ZIP files will be left in the
- work directory. Useful for unattended backup.
-
- 3. MYBACK_SIZE - to the maximum size of file that
- will fit on the floppies you will put in the
- drive specified by MYBACK_DRIVE. I use 1440000
- for 3.5" High density drives.
-
- 4. MYBACK_ZIPCMD - to the complete ZIP command,
- in a special format, that should be used to
- create the ZIP files. The special format is
- the ZIP command and options as you would type
- them on the command line with ZIP file name
- replaced by "%s" and the file containing the
- names of files to be zipped replaced by "%s"
- (as in the printf command.)
- If you use PKZIP, specify "PKZIP -P %s @%s".
- If you use ZIP (from info zip) specify
- "ZIP -@ %s < %s".
-
- 5. MYBACK_SLACK - to the number of bytes you
- are willing to leave unused on each diskette.
- Must be a number. MYBACK will stop adding
- files when it gets this close to the size
- specified in MYBACK_SIZE.
- This variable is optional. The default value
- is 2000 bytes.
-
- Notes: Use great care in setting the environment variable if
- you do it in a CMD or BAT file. In particular, to get
- the proper result for setting MYBACK_ZIPCMD for the
- ZIP program, you need to use the statement:
-
- set MYBACK_ZIPCMD=zip -@ %%s ^< %%s
-
- with the double % signs and the caret(^) in front of
- the left pointing arrowhead. To set up for PKZIP you
- also need the double % signs.
-
- It is recognized that adding files that appear to fit
- to the zip file incrementaly is a decidedly
- non-optimal approach. Some times, it may seem that
- you are asymtotically approaching completion and will
- never be done. It has the advantage, however, of
- being guaranteed (almost) to work. (The almost is
- that it does not account for EAs that ZIP may add to
- the file.) This is likely to be a problem only the
- first time you use it (unless you create humongous
- amounts of data) because your incremental backups
- will probably fit in one ZIP file on 1 HD 3.5 disk.
-
- Use of a reasonable slack value will make the approach
- to completeion go much faster.
-
- Limitations: This program will not handle (will deliberately
- exclude from processing) any file that is bigger than
- the ZIP file size limit. While it is quite possible
- that these files could be handled, there is no way
- to know for sure, and the exception processing code
- to do this was not considered worth the effort.
-
- Zip files are identified by date and letter. This
- means this program can't generate more than 26
- valid ZIP file names. But it doesn't check, so
- beware!
-
- Version:
- Revision 0.00 13Jun93 M.A. Stern (Blue Bird Computing)
- Started coding.
-
- Revision 0.01 16Jun93 M.A. Stern (Blue Bird Computing)
- Add code to read log file.
-
- Revision 0.02 22Jun93 M.A. Stern (Blue Bird Computing)
- Add code to really do ZIPping.
- Add code to write updated log file.
-
- Revision 1.00 22Jun93 M.A. Stern (Blue Bird Computing)
- Released to BSN.
-
- Revision 1.01 23Jun93 M.A. Stern (Blue Bird Computing)
- Minor bugfix.
-
- Revision 1.02 26Jun93 M.A. Stern (Blue Bird Computing)
- Support multiple backups on the same day.
- Re-arrange log file to be a little prettier.
- Don't back up files of length 0.
-
- Revision 1.03 04Jul93 M.A. Stern (Blue Bird Computing)
- Change use of System command to be able to support any ZIPper with
- any command format.
-
- Revision 1.04 06Jul93 M.A. Stern (Blue Bird Computing)
- Add use of an environment variable for "slack" in filling
- diskette.
- Add option to leave ZIP files in work dir if disk="*".
-
- Revision 1.05 07Jul93 M.A. Stern (Blue Bird Computing)
- Some performance optimizations.
-
- Revision 1.06 10Jul93 M.A. Stern (Blue Bird Computing)
- Bugfix on performance optimization.
-
- ****------------------------------------------------------------------*/
-
- /* Initializations */
-
- iZipOvhd = 112; /* Not right for all cases, but close. */
-
-
- main( argc, argv ) {
-
- if ( argc < 3 ) { Usage(); return 0; }
-
- szLogFile = argv[1];
- cPaths = argc - 2;
- aszPathStr[0] = "";
- SetArraySpan( aszPathStr, cPaths -1 );
- iPathInd = 2;
- iFullback = 0;
-
- /* Make sure environment variables have values. */
-
- if ( !Defined( MYBACK_WORK ) ) {
- printf( "Work Directory for ZIP creation: (MYBACK_WORK)"
- " not set.\n")
- return 1;
- }
- szWorkDir = MYBACK_WORK;
-
- if ( !Defined( MYBACK_DRIVE ) ) {
- printf( "Drive to write ZIP files to: (MYBACK_DRIVE)"
- " not set.\n")
- return 1;
- }
- szBackDisk = MYBACK_DRIVE;
-
- if ( !Defined( MYBACK_SIZE ) ) {
- printf( "ZIP file size limit: (MYBACK_SIZE) not set.\n")
- return 1;
- }
- iZipLimit = MYBACK_SIZE;
-
- if ( !Defined( MYBACK_ZIPCMD ) ) {
- printf( "ZIP command and options: (MYBACK_ZIPCMD)"
- " not set.\n")
- return 1;
- }
-
- if ( !Defined( MYBACK_SLACK ) ) {
- printf( "Diskette slack space: (MYBACK_SLACK) not set.\n")
- printf( "Will use 2000 as default.\n")
- iZipSlack = 2000;
- }
- else {
- iZipSlack = MYBACK_SLACK;
- if ( iZipSlack == 0 ) {
- printf( "Diskette slack space: (MYBACK_SLACK) not valid.\n")
- printf( "Will use 2000 as default.\n")
- iZipSlack = 2000;
- }
- }
-
- /* Validate ZIP command format. */
-
- strcpy( szTest, MYBACK_ZIPCMD );
- szS = strstr( szTest, "%s" );
- if ( szS == NULL ) {
- printf( "ZIP command format is incorrect: no %%s found.\n" );
- return 1;
- }
- szS[0] = ' ';
- szS[1] = ' ';
- szS = strstr( szTest, "%s" );
- if ( szS == NULL ) {
- printf( "ZIP command format is incorrect: second %%s not"
- " found.\n" );
- return 1;
- }
-
- /* Validate the paths entered. */
-
- fError = 0;
-
- for( i=0; i<cPaths; i++, iPathInd++ ) {
-
- aszPathStr[i] = argv[iPathInd];
-
- if ( ValidatePath( aszPathStr[i] ) ) {
- fError = 1;
- printf( "Path spec %s is invalid.\n", argv[iPathInd] );
- }
- else printf( "Files will be backed up from %s\n", aszPathStr[i] );
-
- }
-
- if ( fError ) {
- printf( "%s stopping because of errors.\n", argv[0] );
- return 1;
- }
-
- /* Initialize backup log data structure and array so Cmm doesn't
- add one item at a time when we expand it. */
-
- strcpy( BackLog[0].name, "\177\177\177" );
- BackLog[0].size = 1;
- BackLog[0].Write = time();
- strcpy( BackLog[0].zipfile, "99999" );
- BackLog[0].flag = 0;
-
- /* Initialize max used zip file name to an old value. */
-
- strcpy( MaxZip, "000000_A" );
-
- /* Open the log file and read it in. */
-
- fh = fopen( szLogFile, "r" );
- cIndex = 0;
- if ( fh != NULL ) {
-
- /* Read in the data from the file. */
-
- printf( "Will read backup log file %s\n", szLogFile );
-
- szRec = fgets( fh );
-
- while ( !feof( fh ) ) {
- cItems = sscanf( szRec, " %d %d %s %s ", RecSize, RecWrite,
- RecZipfile, RecName );
- if ( cItems < 4 )
- printf( "Insufficient data in backup record %s\n", szRec );
- else {
- BackLog[cIndex].size = RecSize;
- BackLog[cIndex].Write = RecWrite;
- strcpy( BackLog[cIndex].name, RecName );
- strcpy( BackLog[cIndex].zipfile, RecZipfile );
- cIndex++;
-
- /* Check zip file against largest used so far. */
- /* Save the larger value. */
-
- if ( stricmp( RecZipFile, MaxZip ) > 0 )
- strcpy( MaxZip, RecZipFile );
-
- }
-
- szRec = fgets( fh );
-
- }
-
- fclose( fh );
- }
- else {
- printf( "Backup log file %s could not be opened.\n", szLogFile );
- printf( "Will do full backup.\n" );
- iFullback = 1;
- }
-
- /* Add one more (or the only one) element to the backup log that
- will be greater than everything else to act as a terminal
- anchor. */
-
- strcpy( BackLog[cIndex].name, "\177\177\177" );
- BackLog[cIndex].size = 1;
- BackLog[cIndex].Write = time();
- strcpy( BackLog[cIndex].zipfile, "9" );
-
- /* Sort the backup log file by name so we can do simple matching
- to decide what to back up. */
-
- qsort( BackLog, cIndex, "NameCmp" );
-
- /* Get the list of all files that are candidates for backup. */
-
- cFiles = 0;
-
- /* Initialize candidate structure and array so SetArraySpan works
- and we don't have to grow the array one at a time. */
-
- strcpy( Candidates[0].name, "dummy" );
- Candidates[0].size = 1;
- Candidates[0].Write = time();
- Candidates[0].flag = 0;
- strcpy( Candidates[0].zipfile, "0" );
-
- for( i=0; i<cPaths; i++ ) {
-
- iLen = strlen( aszPathStr[i] );
- if ( aszPathStr[i][iLen-1] == '\\' )
- strcpy( szStarStar, "*.*" )
- else
- strcpy( szStarStar, "\\*.*" )
-
- strcat( strcpy( szTemp, aszPathStr[i] ), szStarStar );
-
- ThisSet = Directory( szTemp, TRUE,
- FATTR_ARCHIVE,
- FATTR_ARCHIVE );
- if ( ThisSet == NULL ) {
- printf( "No files found in %s\n", aszPathStr[i] );
- continue;
- }
-
- SetSize = GetArraySpan( ThisSet ) +1;
- NewSize = cFiles + SetSize;
- SetArraySpan( Candidates, NewSize-1 );
-
- for( j=0; j<SetSize; j++ ) {
-
- if ( ThisSet[j].size > 0 ) {
-
- strcpy( Candidates[cFiles].name, ThisSet[j].name );
- Candidates[cFiles].size = ThisSet[j].size;
- Candidates[cFiles].Write = ThisSet[j].Write;
- Candidates[cFiles].flag = 1;
-
- cFiles++;
- }
-
- }
-
- }
-
- if ( cFiles == 0 ) {
- printf( "No files to back up.\n" );
- return 0;
- }
-
- /* Re-adjust size of candidates array because of possiblilty of
- excluded zero length files. */
-
- SetArraySpan( Candidates, cFiles-1 );
-
- /* Sort the list of files by name so regardless of paths given
- on the command line, they will be in order. */
-
- qsort( Candidates, cFiles, "NameCmp" );
-
- /* Remove any duplicate names that ocurred because of path
- overlap. */
-
- cBefore = cFiles;
- RemoveDuplicates( Candidates, cFiles );
- if ( cFiles != cBefore )
- printf( "%d duplicate files removed.\n", cBefore-cFiles );
-
- /* OK, we have backup candidates and the history of prior backups.
- Lets go through the candidates comparing them to what was backed
- up before and decide what needs to be backed up now. */
-
- cToback = cFiles;
- for( i=0, iInd=0; i<cFiles; i++ ) {
-
- iTest = stricmp( Candidates[i].name, BackLog[iInd].name );
- while ( iTest > 0 ) {
- iInd++;
- iTest = stricmp( Candidates[i].name, BackLog[iInd].name );
- }
-
- if ( iTest == 0 ) {
- /* We have a match on name. If other attributes match, the
- file hasn't changed since it was backed up. Turn off the
- flag, so we won't Zip it up again. */
-
- if ( Candidates[i].size == BackLog[iInd].size &&
- Candidates[i].Write == BackLog[iInd].Write ) {
-
- Candidates[i].flag = 0;
- cToback--; /* Decrement backup count. */
-
- } /* if ( Candidates.... */
-
- } /* if ( iTest == 0 ) */
-
- } /* for( i=0, iInd=0; i<cFiles; i++ ) */
-
- /* Make sure there are no files that appear larger than the
- ZIP limit. If there are, remove them as candidates and give
- a message. */
-
- printf( "Checking for large files.\n" );
-
- for( i=0, iInd=0; i<cFiles; i++ ) {
-
- if ( Candidates[i].size > iZipLimit+iZipOvhd ) {
- printf( "File %s is too large to handle.\n",
- Candidates[i].name );
- Candidates[i].flag = 0;
- cToback--; /* Decrement backup count. */
- }
-
- }
-
- if ( cToBack == 0 ) {
- printf( "No files to back up.\n" );
- return 0;
- }
-
- printf( "%d Files need to be backed up.\n", cToback );
-
- /* Get today's date so we can construct the ZIP file names. */
-
- tm = localtime( time() );
- sprintf( szZipFront, "%2.2d%2.2d%2.2d", tm.tm_year, tm.tm_mon+1,
- tm.tm_mday );
-
- for( i=0; i<6; i++ )
- if ( szZipFront[i] == ' ' ) szZipFront[i] = '0';
-
- /* Check this Zip beginning against MaxZip. Use MaxZip if
- it is bigger. */
-
- strupr( MaxZip );
- if ( strncmp( MaxZip, szZipFront, 6 ) > 0 ) {
- printf( "Using ZIP prefix from backup log file.\n" );
- strncpy( zsZipFront, MaxZip, 6 );
- }
-
- printf( "All ZIP files will start with %s\n", szZipFront );
-
- /* Time to make ZIP files. What we do is gather up enough
- candidate files to have the bytes to fill one disk (with ZIP
- overhead). We then ZIP them up and see if we can add more.
- We repeat this until all files that need to be backed up
- have been put in a ZIP file. */
-
- iZipInd = 0;
- iCreated = 0;
- strcpy( szLstFile, szWorkDir );
- strcat( szLstFile, "\\MYBACK.LST" );
-
- iMinInd = 0;
- while( cToback > 0 ) {
-
- szZipFile = MakeZipName( szZipFront, iZipInd, MaxZip );
- strcpy( szFullZip, szWorkDir );
- strcat( szFullZip, "\\" );
- strcat( szFullZip, szZipFile );
- strcat( szFullZip, ".zip" ); /* So we have it for later. */
- remove( szFullZip );
-
- printf( "About to create ZIP file %s.ZIP\n", szZipFile );
-
- iTot = 0;
- fToAdd = 1;
-
- while( iTot < (iZipLimit-iZipSlack) && fToAdd ) {
-
- iToAdd = AddCand( Candidates, iTot, iZipLimit, iMinInd );
-
- if ( iToAdd > 0 ) {
- printf( "%d files to be added this pass.\n", iToAdd );
- iOK = AddToZip( Candidates, szFullZip, szLstFile, iTot,
- iToAdd, iMinInd );
- if ( !iOK ) {
- printf( "Errors ocurred add files to zip file %s\n",
- szFullZip );
- printf( "Program stopping due to errors\n" );
- return 1;
- }
- iTot = GetZipSize( szFullZip );
- MarkZipped( Candidates, szZipFile, iToAdd, iMinInd );
- cToback -= iToAdd;
- }
- else {
- printf( "ZIP file %s is complete.\n", szZipFile );
- fToAdd = 0;
- }
-
- } /* while( iTot < (iZipLimit-iZipSlack) && fToAdd ) */
-
- iTot = GetZipSize( szFullZip );
- if ( iTot > 0 ) {
- if ( strcmp( "*", szBackDisk ) )
- CopyZipToDest( szFullZip, szBackDisk, szZipFile, iTot );
- else printf( "ZIP file left in %s\n", szWorkDir );
- iCreated++
- }
-
- if ( iZipInd > 25 ) {
- printf( "Too many ZIP files for this program.\n" );
- printf( "Stopping.\n" );
- break;
- }
- }
-
- if ( iCreated ) {
-
- printf( "%d ZIP file were created.\nUpdating log file.\n",
- iCreated );
-
- UpdateLogData( Candidates, BackLog );
- WriteBackLog( BackLog, Candidates, szLogFile, iFullback );
-
- }
-
- printf( "Backup complete.\n" );
- return 0;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Update the backup log with data from the candidates that were
- backed up. */
-
- UpdateLogData( Cands, Logs ) {
-
- /* The logic here is to go through both lists (which are still
- sorted) and update log entries for files that have been backed
- up this time around. We don't ADD log entries where they don't
- already exist. Rather we mark these candidate entries as needing
- to be written out to the log later. That way we don't have to
- try and expand the logs array. */
-
- cCand = GetArraySpan( Cands ) +1;
- for( i=0, iInd=0; i<cCand; i++ ) {
-
- /* Note that we already have a search terminator in the
- Logs array from before. */
-
- iTest = stricmp( Cands[i].name, Logs[iInd].name );
- while ( iTest > 0 ) {
- iInd++;
- iTest = stricmp( Cands[i].name, Logs[iInd].name );
- }
-
- if ( iTest == 0 ) {
- /* We have a match on name. If this was backed up (indicated
- by flag=3) we update the logs data with the cadidate data,
- and mark it as already in the log data. */
-
- if ( Cands[i].flag == 3 ) {
-
- Cands[i].flag = 4;
- strcpy( Logs[iInd].zipfile, Cands[i].zipfile );
- Logs[iInd].size = Cands[i].size;
- Logs[iInd].Write = Cands[i].Write;
-
- } /* if ( Cands[i].flag == 3 ) */
-
- } /* if ( iTest == 0 ) */
-
- } /* for( i=0, iInd=0; i<cCand; i++ ) */
-
- return;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Write out the backup log file, re-naming the old version (which
- probably ended up in one of the ZIP files!). */
-
- WriteBackLog( Logs, Cands, szFile, iFull ) {
-
- /* The logic here is to write out the log data, followed by any
- additional candidate data (that was backed up and was new) to
- the log file. We could merge the two sets and sort, but why
- bother when we will sort the log when it is read in next time. */
-
- /* First parse the file name and make two alternate file names:
- one for the new file, and one for the "bak" file. */
-
- Parts = SplitFileName( szFile );
-
- OldExt = Parts.ext;
- if ( !stricmp( OldExt, ".BAK" ) )
- strcpy( BakExt, ".BAC" )
- else strcpy( BakExt, ".BAK" )
-
- if ( !stricmp( OldExt, ".$$$" ) )
- strcpy( NewExt, ".$$1" )
- else strcpy( NewExt, ".$$$" )
-
- strcpy( szBakFile, Parts.name );
- strcat( szBakFile, BakExt );
-
- strcpy( szNewFile, Parts.dir );
- strcat( szNewFile, Parts.name );
- strcat( szNewFile, NewExt );
-
- strcpy( szFullBak, Parts.dir ); /* To remove old bak file. */
- strcat( szFullBak, szBakFile );
-
- strcpy( szOldFile, Parts.name );
- strcat( szOldFile, OldExt );
-
- fh = fopen( szNewFile, "w" );
- if ( fh == NULL ) {
- printf( "New log file (%s) could not be opened\n", szNewFile );
- exit(1);
- }
-
- /* Write out the data. */
-
- cLogs = GetArraySpan( Logs ); /* Note no extra 1 for trailer! */
- cCand = GetArraySpan( Cands ) +1;
-
- for( i=0; i<cLogs; i++ )
- fprintf( fh, "%10.d %10.d %s %s \n", Logs[i].size,
- Logs[i].Write, Logs[i].zipfile, Logs[i].name );
-
- for( i=0; i<cCand; i++ )
- if ( Cands[i].flag == 3 )
- fprintf( fh, "%10.d %10.d %s %s \n", Cands[i].size,
- Cands[i].Write, Cands[i].zipfile, Cands[i].name );
-
- fclose( fh );
-
- /* Now rename the files. */
-
- remove( szFullBak );
- if ( !iFull )
- iRc = rename( szFile, szBakFile );
- else iRc = 0;
- if ( iRc != 0 ) {
- printf( "Rename of %s to %s failed. New log file is %s\n",
- szFile, szBakFile, szNewFile );
- exit(1);
- }
-
- iRc = rename( szNewFile, szOldFile );
- if ( iRc != 0 ) {
- printf( "Rename of %s to %s failed. New log file is %s\n",
- szNewFile, szOldFile, szNewFile );
- exit(1);
- }
-
- return 0;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Copy a ZIP file to it's final destination and erase it on the disk */
-
- CopyZipToDest( szFullZip, szDest, szBaseZip, iSize ) {
-
- strcpy( szSysCmd, "copy " );
- strcat( szSysCmd, szFullZip );
- strcat( szSysCmd, " " );
- strcat( szSysCmd, szDest );
-
- strcpy( szFloppyZip, szDest );
- strcat( szFloppyZip, szBaseZip );
- strcat( szFloppyZip, ".zip" );
-
- Retry:
- printf( "Please put a blank formatted diskette in drive %s\n",
- szDest );
- printf( "Press a key when ready..." );
- c = getch();
- printf( "\n" );
-
- system( szSysCmd );
-
- Data = Directory( szFloppyZip, FALSE, FATTR_ARCHIVE, 0);
- if ( Data != NULL )
- if ( Data[0].size == iSize ) {
- printf( "Copy successful.\n" );
- remove( szFullZip );
- return;
- }
-
- printf( "Copy to floppy failed.\n" );
-
- while ( 1 ) {
- printf( "Press Q to quit, R to retry, or I to Ignore: " );
- c = getche();
- if ( c != '\n' ) printf( "\n" );
- c = toupper( c );
- if ( c == 'Q' ) exit(1);
- if ( c == 'R' ) goto Retry;
- if ( c == 'I' ) return;
- }
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Get the actual total bytes of a ZIP file. */
-
- GetZipSize( szZip ) {
-
- Size = 0;
- Data = Directory( szZip, FALSE, FATTR_ARCHIVE, 0);
- if ( Data != NULL ) Size = Data[0].size;
- return Size;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Mark files as being in a ZIP file and save ZIP file name. */
-
- MarkZipped( Cands, szZip, iToAdd, iMinIndex ) {
-
- iNumCand = GetArraySpan( Cands ) +1;
- iNum = 0
-
- for( i=iMinIndex; i<iNumCand && iNum<iToAdd; i++ ) {
-
- if ( Cands[i].flag == 2 ) {
-
- Cands[i].flag = 3;
- strcpy( Cands[i].zipfile, szZip );
- iNum++;
-
- }
-
- } /* for( i=iMinIndex; i<iNumCand && iNum<iToAdd; i++ ) */
-
- return;
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Add marked files to a ZIP file using the system() command. */
-
- AddToZip( Cands, szZip, szList, iTot, iToAdd, iMinIndex ) {
-
- iNumCand = GetArraySpan( Cands ) +1;
- iNum = 0
-
- fh = fopen( szList, "w" );
- if ( fh == NULL ) {
- printf( "Could not open list file %s\n", szList );
- return 0;
- }
-
- for( i=iMinIndex; i<iNumCand && iNum<iToAdd; i++ ) {
-
- if ( Cands[i].flag == 2 ) {
- fprintf( fh, "%s\n", Cands[i].name );
- iNum++;
- }
-
- } /* for( i=iMinIndex; i<iNumCand && iNum<iToAdd; i++ ) */
-
- fclose( fh );
-
- if ( iNum == 0 ) {
- printf( "No candidates found to add\n" );
- remove( szList );
- return 0;
- }
-
- /* Do the ZIP command. */
-
- strcpy( szZipCmd, MYBACK_ZIPCMD );
- iRc = system( szZipCmd, szZip, szList );
-
- remove( szList );
- if ( !iRc ) return 1;
- else return 0;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Determine what files can fit in the current ZIP file on the
- current pass and mark them as such. */
-
- AddCand( Cands, iZipCum, iLimit, iMinIndex ) {
-
- iNumCand = GetArraySpan( Cands ) +1;
- iToAdd = 0;
- iNewMin = -1;
-
- for( i=iMinIndex; i<iNumCand && iToAdd<100; i++ ) {
-
- if ( Cands[i].flag == 1 ) {
-
- if ( iNewMin == -1 ) iNewMin = i;
- iBytes = Cands[i].size + iZipOvhd;
-
- if ( iZipCum+iBytes < iLimit ) {
-
- iZipCum+= iBytes;
- Cands[i].flag = 2;
- iToAdd++;
-
- } /* if ( iZipCum+iBytes < iLimit ) */
-
- } /* if ( Cands[i].flag == 1 ) */
-
- } /* for( i=iMinIndex; i<iNumCand; i++ ) */
-
- if ( iToAdd ) iMinIndex = iNewMin;
- return iToAdd;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Make sequential names for ZIP files. */
-
- MakeZipName( szFront, iInd, MaxVal ) {
-
- Again:
-
- strcpy( szLetter, " " );
- szLetter[0] = 'A' + iInd;
- strcpy( szZip, szFront );
- strcat( szZip, "_" );
- strcat( szZip, szLetter );
- iInd++;
-
- if ( strcmp( MaxVal, szZip ) >= 0 ) goto Again;
-
- return( szZip );
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Validate a backup path spec. */
-
- ValidatePath( szPath ) {
-
- iLen =strlen( szPath );
- c = szPath[iLen-1];
- if ( c == '\\' ) {
- if ( !(iLen == 3 && szPath[1] == ':' && isalpha( szPath[0] ) ) )
- szPath[iLen-1] = 0;
- }
-
- printf( "Path to check is %s\n", szPath );
-
- /* Check for wildcards. */
-
- if ( strchr( szPath, '*' ) != NULL ) return 1;
- if ( strchr( szPath, '?' ) != NULL ) return 1;
-
- szTemp = FullPath( szPath ) ;
-
- if ( szTemp == NULL ) return 1;
- strcpy( szPath, szTemp );
- return 0;
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Compare the name elements of a structure. */
-
- NameCmp( Elem1, Elem2 ) { return stricmp( Elem1.name, Elem2.name ) }
-
-
- /*--------------------------------------------------------------------*/
- /* Remove duplicate entries by name. The array of structures must
- be sorted. */
-
- RemoveDuplicates( WorkStruct, iSize ) {
-
- iTot = iSize;
-
- for( i=1; i<iSize; i++ )
- if ( !stricmp( WorkStruct[i-1].name, WorkStruct[i].name ) ) {
- strcpy( WorkStruct[i-1].name, "\177\177\177" );
- iTot--;
- }
-
- /* Now see if there were any duplicates to remove. If so, they
- will end up at the end of the range when we sort the data, and
- we can lop them off with SetArraySpan. */
-
- if ( iTot != iSize ) {
-
- qsort( WorkStruct, iSize, "NameCmp" );
- SetArraySpan( WorkStruct, iTot-1 );
- iSize = iTot;
- }
-
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Print usage info. This is real brief right now. */
-
- Usage() {
- printf( "Usage:\tMyback logfile directory ....\n" );
- return 0;
- }
-
-